#include "StdAfx.h"
#include "text_filter.h"

#include "pinyin_util.h"
using namespace algorithm4cpp;

bool text_filter::contains_keyword( const wchar_t * text, size_t length, int flags ) const
{
#pragma warning( disable: 4800 )
	bool ignore_case = flags & filter_flags::IGNORE_CASE;
	bool ignore_sbc = flags & filter_flags::IGNORE_SBC;
	bool ignore_special = flags & filter_flags::IGNORE_SPECIAL;
	bool ignore_number = flags & filter_flags::IGNORE_NUMBER;
	bool ignore_non_chinese = flags & filter_flags::IGNORE_NON_CHINESE;
#pragma warning( default: 4800 )

	trace_list traces;
	for ( size_t pos = 0; pos < length; ++pos ) {
		wchar_t c = text[pos];
		c = to_alias(c, ignore_case, ignore_sbc);

		trace_list ignored_traces;
		if ( ( ignore_special && specials_.find(c) != specials_.end() ) ||
			( ignore_number && ::iswdigit(c) )	||
			( ignore_non_chinese && ! pinyin_util::is_chinese(c) )				
			) {
				ignored_traces = traces;
		}

		// push global forest to last traces
		traces.push_back( 
			trace_ptr( 
			pool.construct( 0, trace::no_pos, dictionary_ ),
			::boost::bind( &trace_pool::destroy, &pool, _1 )
			) 
			);

		// filter from previous result maps, remove non-continuous string
		trace_ptr t = filter_traces( traces, c, pos );
		if ( t ) {
			++hits_;
			return true;
		}

		for( trace_list::const_iterator it = ignored_traces.begin(); 
			it != ignored_traces.end(); ++it ) {
				traces.push_back( *it );
		}
	}

	return false;
}

bool text_filter::replace_keyword( wchar_t * text, size_t length, wchar_t replace, int flags ) const
{
#pragma warning( disable: 4800 )
	bool ignore_case = flags & filter_flags::IGNORE_CASE;
	bool ignore_sbc = flags & filter_flags::IGNORE_SBC;
	bool ignore_special = flags & filter_flags::IGNORE_SPECIAL;
	bool ignore_number = flags & filter_flags::IGNORE_NUMBER;
	bool ignore_non_chinese = flags & filter_flags::IGNORE_NON_CHINESE;
#pragma warning( default: 4800 )

	trace_list traces;
	for ( size_t i = 0; i < length; ++i ) {
		wchar_t c = text[i];
		c = to_alias(c, ignore_case, ignore_sbc);

		trace_list ignored_traces;
		if ( ( ignore_special && specials_.find(c) != specials_.end() ) ||
			( ignore_number && isdigit(c) )	||
			( ignore_non_chinese && ! pinyin_util::is_chinese(c) )				
			) {
				ignored_traces = traces;
		}

		// push global forest to last traces
		traces.push_back( 
			trace_ptr( 
			pool.construct( 0, trace::no_pos, dictionary_ ),
			::boost::bind( &trace_pool::destroy, &pool, _1 )
			) 
			);

		// filter from previous result maps, remove non-continuous string
		trace_ptr t = filter_traces( traces, c, i );
		if ( t ) {
			traces.clear();
			replace_text( text, length, replace, t );
			++hits_;
		}

		for( trace_list::const_iterator it = ignored_traces.begin(); 
			it != ignored_traces.end(); ++it ) {
				traces.push_back( *it );
		}
	}

	return true;
}